package com.zhenyi.websocket.core.ws;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;

import cn.hutool.core.lang.Singleton;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.ChannelMatcher;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

public class WSServer {
	protected Cache cache = Redis.use();
	private WSUtils wsUtils = new WSUtils();
	public final static String WS_FIELD_MAP = "WS_CONNECTION_MAP";
	public final static String WS_FIELD = "WS_CONNECTION";
	public final ChannelGroup allChannels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

	public void start() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				try {
					cache.del(WS_FIELD);
					cache.del(WS_FIELD_MAP);
					wsUtils.start();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

	public void stop() {
		wsUtils.stop();
	}

	// public static void main(String[] args) {
	// WSServer wsServer = new WSServer();
	// wsServer.start();
	// }

	public void sendByToken(String token, String json) {
		if (StrKit.isBlank(json)) {
			return;
		}
		String uid = cache.hget(WS_FIELD_MAP, token);
		send(json, uid);
	}

	public void send(String json, String uid) {
		if (StrKit.isBlank(json)) {
			return;
		}
		allChannels.writeAndFlush(new TextWebSocketFrame(json), getMatcher(uid));
	}

	public void send(String json) {
		if (StrKit.isBlank(json)) {
			return;
		}
		allChannels.writeAndFlush(new TextWebSocketFrame(json));
	}

	public static WSServer instance() {
		return Singleton.get(WSServer.class);
	}

	public ChannelMatcher getMatcher(final String uid) {
		return new ChannelMatcher() {

			@Override
			public boolean matches(Channel channel) {
				return channel.id().asLongText().equals(uid);
			}
		};
	}
}
